package org.chnxi.study.nio.netty.groupchat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class NioGroupChatServerHandler extends SimpleChannelInboundHandler<String> {

    // 定义一个ChannelGroup，用于管理所有在连接的channel
    // GlobalEventExecutor.INSTANCE 是一个全局的事件执行器，是一个单利
    private static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    private static DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    /**
     * 表示有新的客户端建立了连接
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        group.writeAndFlush("["+dtf.format(LocalDateTime.now())+"][客户端]["+channel.remoteAddress()+"]进来了！\n");
        group.add(channel);
    }

    /**
     * 表示当前channel处于活动状态
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("["+dtf.format(LocalDateTime.now())+"][服务端]"+ctx.channel().remoteAddress()+"进来了！");
    }

    /**
     * 表示当前channel处于不活动状态
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println("["+dtf.format(LocalDateTime.now())+"][服务端]"+ctx.channel().remoteAddress()+"离开了！");
    }

    /**
     * 表示客户端已经断开连接
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        group.writeAndFlush("["+dtf.format(LocalDateTime.now())+"][客户端]["+ctx.channel().remoteAddress()+"]离开了！\n");
    }

    /**
     * 表示接收到某个客户端发送的消息
     */
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String msg) throws Exception {
        Channel curChannel = channelHandlerContext.channel();
        final String text = "["+dtf.format(LocalDateTime.now())+"][客户端]["+curChannel.remoteAddress()+"]说："+msg+"\n";
        //向其他客户端推送消息
        group.forEach( channel ->{
            if(channel != curChannel){
                channel.writeAndFlush(text);
            }else{
                channel.writeAndFlush("["+dtf.format(LocalDateTime.now())+"]消息已送达");
            }
        });
    }

    /**
     * 表示发生异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
